为了有效地完成数据存储任务,需要对存储器做如下处理:
1 划分:以字节(8个位bit,对应8个开关晶体管,0或1)为单位将存储器划分为一系列的存储单元。
2 编址:以线性方式给每个存储单元赋予唯一的存储地址,可以随机访问。
3 数据存储约定:数据以二进制形式放入存储空间,需要约定数据的存储空间大小、存储空间地址、数据编码和解码方式以及字节排序方式。如一个基本类型需要多字节时,用大头地址还是小头地址做为数据的地址?
3.1 数据的编码和解码方式
I 以补码方式存储整数;C++|一个简单的变量声明背后复杂的语法概念与存储实现
II 通过ASCII编码方式存储字符;
III 以real-4或real-8方式存储浮点数(实数或小数);
3.2 大头还是小头,按理说只要统一约定就好,但是Intel公司的机器多采用小头方式,IBM、Sun等公司采用大头方式。一般情况下,可以不考虑字节排序方式的问题,但是在针对网络应用编写程序时,就必须关注使用哪种字节排序方式,这是因为网络程序通常需要在不同类型的机器之间交换数据。
为什么是不个bit为一个byte做为最小(基本)的存储单元呢?2^3=8,指数计算方便,另位2^8=256,能够包含全部英文字母+数字+一些基本常用的符号。
下面的变量声明和定义就暗含了上面全部的内容。
double PriceOfRice;
数据=数据规格(类型)+数据地址(变量名)
数据规格=存储空间大小+编码和解码方式+可接受的运算处理
1 在内存中开辟一个8个字节的内存单元,可以通过sizeof(double)得到字节数;
2 该段内存单元的地址用PriceOfRice来表示;
3 此时的值是一个随机值,因为每个字节的每个位都是随机的0或1。如此时用代码cout<<PriceOfRice访问其值,可以显示:-9.25596e+0618,但你在一些操作后再去访问,其值可能不一样了。
另外,PriceOfRice的取名有诸多要求和考究,例如,不能使用关键字,不能用数字开头,如建议能见名知义,通过名字而不是通过注释去了解其含义。
给变量赋值:
PriceOfRice =3.18;
3.18是字面量,属于代码部分,不可寻址,3.18按real-8的编码方案编码(一串01)后放到PriceOfRice对应的内存空间(每个比特或0或1)。
字面量写法:
浮点型字面量也可以写成.46、1.e20、2.3f、123e12、1.e4L、-.34e-2f;
整形字面量:157、-0655、0xFE、-0x1UL;
字符型字面量:'C'、'ab'、'$'、'\n'、'\x61'、L'中'、L'a';
布尔型字面量:true、false;
字符串型字面量:"C++ programming"、L"abc"、"\x41\x42\x43"(ABC);
除了字符串型字面量,其它字面量都不可寻址,字符串型字面量存储在被分配的内存空间的数据段。
另外,两行代码写到一起:double PriceOfRice =3.18;
表示变量声明、定义、初始化同时完成。
关于初始化的内容,请见:《C++|变量、对象、对象成员初始化的一些细节》。
对于代码:PriceOfRice = PriceOfRice *1.1
表示右边的PriceOfRice表示取值,乘以1.1,按double的编码方案编码后放到左边的PriceOfRice对应的内存单元。
C++左值和右值的概念:左值表示一种可以定位的存储空间,右值表示从存储空间中临时读取的数据值。左值可以做右值,右值不能用做左值。
而乘法运算符*则表示了double这种类型可接受的运算处理,如double就能不使用取余运算符%,而指针类型一般不会使用*来做运算(指针一般用其做解运算)。
下面是一个关于整数编码的小实例:
#include <iostream>
using namespace std;
int main()
{
unsigned long unl = -0x1UL;
unsigned long ul = 0x1UL;
long l = -0x1L;
cout<<unl<<endl;//4294967295
cout<<ul<<endl;//1
cout<<l<<endl;//-1
cout<<hex<<unl<<endl;
cout<<ul<<endl;
cout<<l<<endl;
cout<<sizeof(long)<<endl;
//正数的原码、反码、补码都相同
//负数补码:原码的符号位(最高位)不变,其余位取反,然后再加1
//原码:10000000 00000000 00000000 00000001(最高位是符号位)
//反码:11111111 11111111 11111111 11111110(符号位不变,其余取反)
//补码:11111111 11111111 11111111 11111111(反码加1)
system("pause");
return 0;
}
/*
4294967295
1
-1
ffffffff
1
ffffffff
4
*/
另外,double PriceOfRice;写在不同的位置,或者前面有诸如static、external等不同的限定词,决定了其有不同的作用域和存续期,同时也确定了其存储在被分配给程序的一块内存空间中不同的区域(栈区、全局区\静态区等)。
变量规定了名字和数据类型的存储空间,执行程序就是促使变量的存储空间状态发生变化,并达到预期状态的。因此,编程时应该能够随时在大脑中描绘出变量相对应的存储空间状态,称为存储空间映像。
-End-
本页共71段,2476个字符,5289 Byte(字节)